package com.mxcyk.plug.shell;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/*控制台窗口
 * 这种方法最直接，但是没有下一行时，scanner.hasNextLine()会阻塞在那边，直到下一个换行符。
 *  所以这样感觉和dos窗口有少许区别：dos窗口有一个如“c:Usersmacondo>_”这样的东西提示你输入下一个命令；
 *  而以上程序效果是你输入命令后那个提示才出来。原因是那个提示后面没有换行符，等到有换行符时才会被输出。
 *   下面是一种解决方法：用timer定时检查inputstream，有东西就把它输出来：
 */
final public class Cmd extends JPanel implements KeyListener {
	public static JTextArea jtaCmd;
	private static Process process = null;
	private static PrintWriter writer = null;
	private JScrollPane scroll;// 文本的滚动条

	public static void main(String... args) {
		// /////////////////////////////////////////////////////////////////////////////////////////////
		JFrame jfm = new JFrame("cmd");
		jfm.add(new Cmd());
		jfm.setVisible(true);
		jfm.setSize(400, 600);
		jfm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设定窗体关闭后自动退出进程
		// ////////////////////////////////////////////////////////////////////////////////////////////
	}

	public Cmd() {

		try {
			process = Runtime.getRuntime().exec("cmd");
			writer = new PrintWriter(process.getOutputStream());

		} catch (IOException e1) {
			// TODO Auto-generated catch block
			System.out.println("启动控制台出错!\n位于Cmd类的构造函数内");
			e1.printStackTrace();
		}

		final InputStream inputStream = process.getInputStream();
		final InputStream err = process.getErrorStream();
		final byte[] b = new byte[1024];
		javax.swing.Timer timer = tmeerscan(b, inputStream, err);
		timer.start();

		this.setLayout(new BorderLayout());
		jtaCmd = new JTextArea();
		scroll = new JScrollPane(jtaCmd);
		// 垂直滚动条一直显示
		scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		this.add(scroll);
		jtaCmd.addKeyListener(this);// 注册监听类
	}

	public static void getAccation(String Accation) {
		writer.println(Accation);
		writer.flush();
	}

	// 定时扫描控制台
	private static javax.swing.Timer tmeerscan(final byte[] b,
			final InputStream inputStream, final InputStream err) {
		javax.swing.Timer timer = new javax.swing.Timer(400,
				new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						// TODO Auto-generated method stub

						try {
							while (inputStream.available() != 0) {
								int c = inputStream.read(b, 0, b.length);
								// System.out.print(new String(b, 0, c));
								/*String output=new String(b, 0, c);
								output=new String(output.getBytes("gbk"),"utf-8");*/
								jtaCmd.append(/*output*/new String(b, 0, c));// 追加到JTextArea
							}
						} catch (Exception ee) {
							// TODO: handle exception
						}

						try {
							while (err.available() > 0) {
								int c = err.read(b, 0, b.length);
								// System.out.print(new String(b, 0, c));
								jtaCmd.append(new String(b, 0, c));// 追加到JTextArea
							}
						} catch (Exception ee) {
							// TODO: handle exception
						}
					}
				});
		return timer;
	}
	
	private static String commend = new String("");
	@Override
	public void keyPressed(KeyEvent e) {
		/*
		 * 代码解释：此段代码是监听文本框的按键事件 并记录按下的按键直到输入回车键时将以上所输入的字符串穿的给命令调用getAccation();
		 */
		if (e.getKeyChar() != '\n') {
			commend += e.getKeyChar();
		} else {
			 System.out.print("" + commend/*e.getKeyChar()*/);
			if(commend.equalsIgnoreCase("exit")){//忽略exit命令
				commend = "";
				//System.out.println("匹配成功");
			}
			getAccation(commend);// 执行获得的命令
			commend = "";
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
	}
}
